#ifndef NOTE_DIALOG_BASE_H
#define NOTE_DIALOG_BASE_H

#define MAX_DISPLAYED_NOTES 1000

#include <wx/scrolwin.h>
#include <wx/textctrl.h>
#include <vector>
#include "note.h"
#include "debug.h"
#include "render.h"
#include "apptab.h"

class wxSizeEvent;
class wxMouseEvent;
class wxScrollWinEvent;
class wxCommandEvent;
class wxKeyEvent;
class wxBoxSizer;
class wxPanel;
class wxTextCtrl;
class wxStaticText;
class wxStaticLine;
class AppFrame;
class TextLayout;

using std::vector;

class NotesPanelBase: public wxScrolledCanvas, public AppTab
{
protected:

    RenderOptions render_options;

    /// These objects are suplied as user data to callback on every wxTextCtrl
    /// so they have to inherit wxObject and they have to contain all info needed in callbacks
    class DispItem : public wxObject, private InstanceWatcher<DispItem>
    {
    public:
        DispItem(wxTextCtrl* wxtext, int index, wxStaticLine* separator) : wxObject() {
            this->wxtext = wxtext;
            this->index = index;
            this->separator = separator;
        }
        ~DispItem() {
        }
        wxTextCtrl* wxtext;
        wxStaticLine* separator;
        int index;
    };

private:

    vector<DispItem*> disp_items;
    int wrap_width;
    DispItem *selected_item;

    bool needs_gtk_fix;

    void OnSize(wxSizeEvent& event);
    void OnClick(wxMouseEvent& event);
    void OnDoubleClick(wxMouseEvent& event);
    void OnRightClick(wxMouseEvent& event);
    void OnPopupClick(wxCommandEvent& event);
    void OnScroll(wxScrollWinEvent& event);
    void OnKeyDown(wxKeyEvent& event);
    void GTKFix(wxUpdateUIEvent& event);
    void CheckIntegrity() const;

protected:
    bool display_ok;                    // not a very nice hack, see comment in OnSize
    wxStaticLine* caption_separator;
    AppFrame *top_frame;
    vector<TextItem> items;

    int selection_index;

    void LoadNotes(const vector<Note>& notes);
    void InsertItemAt(const TextItem& note, unsigned index);
    void RemoveItemAt(int index);
    void RemoveNote(const Note &n);
    void RemoveKeyword(const Keyword &k);
    int  FindNoteIndexByID(int id);
    int  FindNoteIndexByContent(const Note& n);
    int  FindKeywordIndexByID(int id);

public:
    NotesPanelBase(AppFrame* top_frame, wxWindow* parent);

    // navigation
    void ScrollDown();
    void ScrollUp();
    void SelectNext();
    void SelectPrev();

    void ClearDisplay();
    void UpdateDisplay();

    // user-level item manipulation
    wxString GetItemTitle(int index) const;
    wxString GetItemInfo(int index) const;
    void SetSelection(int new_index);
    void EditItem(int index);
    void CopyItemToClipboard(int index);
    void DeleteItem(int index);

    //
    inline unsigned GetItemCount() const {return items.size();}
    bool ContainsNoteID(int id) const;
    bool ContainsNote(const Note& n) const;

    virtual void NotifyChangedAppearance();
};

#endif
